package com.zookeeper.demo;

import com.zookeeper.utils.ConnectionUtil;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * @Author 咕唧
 * @Date 2022/6/29 20:01
 * @Version 1.0
 */
public class ZookeeperBase {
    //阻塞时使用，参数表示需要放行的次数
    private static CountDownLatch countDownLatch = new CountDownLatch(1);

    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        //异步连接zookeeper
        ZooKeeper zooKeeper = new ZooKeeper(ConnectionUtil.SERVER_ADDRESS, 10000, new Watcher() {
            /**
             * 告诉我们当前发生的事件
             * @param watchedEvent
             */
            @Override
            public void process(WatchedEvent watchedEvent) {
                System.err.println("ZookeeperBase的process方法执行了");
                //事件的状态
                Event.KeeperState state = watchedEvent.getState();
                //事件的类型
                Event.EventType type = watchedEvent.getType();
                //判断当前的连接状态是否是成功
                if (state == Event.KeeperState.SyncConnected) {
                    //NONE代表是连接成功
                    if (type == Event.EventType.None) {
                        System.err.println("连接zookeeper成功");
                    }
                }
                //放行
                countDownLatch.countDown();
            }
        });
        countDownLatch.await();
        System.err.println("程序运行完成");

        System.err.println("--------华丽的分割线------");
        //创建节点,是一个持久化的节点,重复创建会提示节点已经存在异常
        String result = zooKeeper.create("/java", "ceshishuju".getBytes(StandardCharsets.UTF_8), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        System.err.println("creeat返回的数据是==>" + result);


        /**
         * 获取节点的数据,
         * 参数1,目录地址。参数2 是否监控, 如果设置为true,当这个节点发生变化的时候会通过之前的watcher来告诉我们,
         * 参数3, 状态, 我们的数据有zxid, 每个数据都有版本号, 可以视为是一个乐观锁,
         * 我们需要指定版本号, 服务端上面的版本号和我们传递的一样才有数据 null不考虑版本号
         */
        byte[] data = zooKeeper.getData("/java", false, null);
        String s = new String(data);
        System.err.println(s);
        //获取子节点
        List<String> children = zooKeeper.getChildren("/java", true);
        System.err.println("子节点数据"+children);
        //获取所有子节点的数据
        children.stream().forEach(child->{
            try {
                String path="/java"+child;
                byte[] data1 = zooKeeper.getData(path, false, null);
                String s1 = new String(data1);
                System.err.println(s1);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
        //查询节点的状态
//        ZooKeeper.States state = zooKeeper.getState();
        Stat stat = zooKeeper.exists("/java", true);
        //查看版本号
        int version = stat.getVersion();
        System.err.println(stat+"---"+version);
        //我们可以根据查询到的状态来更新数据
        Stat stat1 = zooKeeper.setData("/java", "xindeshuju".getBytes(StandardCharsets.UTF_8), version);
        //忽略版本号更新, 写-1
        //zooKeeper.setData("/gp11", "aaaaa".getBytes(StandardCharsets.UTF_8), -1);
        //删除数据，如果节点中存在子节点，删除会报错，需要遍历删除所有子节点
        zooKeeper.delete("/java", -1);
        //遍历删除所有的子节点
        List<String> children1 = zooKeeper.getChildren("/java", false);
        children1.stream().forEach(child->{
            String path="/java"+child;
            try {
                zooKeeper.delete(path, -1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (KeeperException e) {
                e.printStackTrace();
            }
        });
        System.err.println("程序运行完成");
        //关闭连接
        zooKeeper.close();
    }
}
